import G6, { IGroup, Item } from '@antv/g6';
import enterPng from '@/assets/images/analysis/exception/enterService.png';
import editPng from '@/assets/images/analysis/exception/edit.png';
import closePng from '@/assets/images/close-o.png';
import Cluster from '@/assets/images/analysis/exception/cluster.svg';
import { workloadTypes, nodeActiveImgHandle,  getNodeImg,fittingString } from './service';
// import { fittingString } from './topoService_new';
import _ from 'lodash';
import { getStore } from '@/services/util';

const absUrl = window.location.protocol + '//' + window.location.host;
const nodeW = 50,
    nodeH = 50;
const ImgW = 30,
    ImgH = 30;

const nodeColors = {
    // 暂时注释 万一哪天节点颜色又和type走了。。
    // service: '#5584ef',
    // workload: '#7dcf50',
    // gateway: '#f54242',
    // f5: '#32c5ff',
    // deployment: '#7dcf50',
    // statefulset: '#7dcf50',
    // daemonset: '#7dcf50',
    // job: '#7dcf50',
    // cronjob: '#7dcf50',
    // slb: '#f7961e',
    // vm: '#f7961e',
    // other: '#f7961e',
    // '': '#F6BF41',
    0: '#1486DB',   // 正常
    1: '#F7313B',   // 故障(红色)
    2: '#CB8C30',   // 异常(黄色)
};
const nodeFillColors = {
    // service: '#f2f6ff',
    // workload: '#f2ffeb',
    // gateway: '#fff0f0',
    // f5: '#effbff',
    // deployment: '#f2ffeb',
    // statefulset: '#f2ffeb',
    // daemonset: '#f2ffeb',
    // job: '#f2ffeb',
    // cronjob: '#f2ffeb',
    // slb: '#fff7ed',
    // vm: '#fff7ed',
    // other: '#fff7ed',
    // '': '#FFF8E8',
    0: 'rgba(20, 134, 219, 0.12)',  // 正常
    1: 'rgba(247, 49, 59, 0.12)',   // 故障(红色)
    2: 'rgba(203, 140, 48, 0.12)',  // 异常(黄色)
};
// 注册自定义节点
G6.registerNode(
    'custom-topo-node',
    {
        draw: (node, group) => {
            const self = this;

            const theme = getStore('theme') || 'light';
            const nodeStatus = node.state && node.state.status ? node.state.status : 0;
            const shape = group.addShape('circle', {
                attrs: {
                    x: 0,
                    y: 0,
                    r: nodeW / 2,
                    height: nodeH,
                    lineWidth: 1,
                    fill: nodeFillColors[nodeStatus],
                    stroke: nodeColors[nodeStatus],
                    opacity: node.isInBusiness === false ? 0.4 : 1,
                    filter: node.isInBusiness === false ? 'grayscale(1)' : 'grayscale(0)',
                },
                id: 'node-circle',
                name: 'node-circle',
                draggable: true,
            });
            // 焦点的外圈
            group.addShape('circle', {
                attrs: {
                    x: 0,
                    y: 0,
                    r: nodeW / 2 + 5,
                    height: nodeH,
                    lineWidth: 1,
                    stroke: theme === 'dark' ? 'rgba(255, 255, 255, 0)' : 'rgba(0, 0, 0, 0)',
                },
                id: 'node-out-circle',
                name: 'node-out-circle',
                draggable: true,
            });
            group.addShape('image', {
                attrs: {
                    x: -ImgW / 2,
                    y: -ImgW / 2,
                    width: ImgW,
                    height: ImgH,
                    cursor: 'pointer',
                    opacity: node.isInBusiness === false ? 0.4 : 1,
                    filter: node.isInBusiness === false ? 'grayscale(1)' : 'grayscale(0)',
                    img:
                        node.isCenter && node.isSelected
                            ? nodeActiveImgHandle(node.nodeType)
                            : getNodeImg(node.nodeType, nodeStatus),
                },
                name: 'node-image',
                id: 'node-image',
                draggable: true,
            });
            // 该节点是否有上下游节点标识
            if (node.existsInOrOutDegree) {
                group.addShape('circle', {
                    attrs: {
                        x: 14.5,
                        y: -nodeH / 2 + 4.5,
                        r: 4.5,
                        fill: nodeColors[nodeStatus],
                    },
                    id: 'node-adjacent-badge',
                    name: 'node-adjacent-badge',
                    draggable: true,
                });
            }

            const nodeName = node.nameBak && node.nameBak !== node.name ? `${node.nameBak}(${node.name})` : node.name;
            const text = nodeName && fittingString(nodeName, 60, 10);
            group.addShape('text', {
                attrs: {
                    x: 0,
                    y: nodeH / 2 + 6,
                    textAlign: 'center',
                    textBaseline: 'top',
                    class: 'node_text',
                    fontSize: 10,
                    lineHeight: 10,
                    text,
                    fill: theme === 'dark' ? 'rgba(255, 255, 255, 0.65)' : '#595959',
                },
                id: 'node-name',
                name: 'node-name',
            });
            if (node.isEntrance) {
                const [textWidth] = G6.Util.getTextSize(text, 10);
                group.addShape('image', {
                    attrs: {
                        x: -(textWidth / 2) - 18,
                        y: nodeH / 2 + 2,
                        width: 15,
                        height: 15,
                        cursor: 'pointer',
                        img: absUrl + enterPng,
                    },
                    id: 'entrance-image',
                    name: 'entrance-image',
                });
            }
            if (node.supportEditName && workloadTypes.indexOf(node.nodeType) > -1) {
                group.addShape('image', {
                    attrs: {
                        x: 28,
                        y: nodeH / 2 + 3.5,
                        width: 15,
                        height: 15,
                        cursor: 'pointer',
                        img: absUrl + editPng,
                    },
                    id: 'edit-image',
                    name: 'edit-image',
                });
            }
            if (node.masterName) {
                // 集群名称
                let text = node.masterName;
                if (!node.mergeLabel && node.workloadKind !== 'vm') {
                    text = `${node.masterName} - ${node.namespace}`;
                }
                // 集群框
                group.addShape('rect', {
                    attrs: {
                        x: 0,
                        y: nodeH / 2 + 18,
                        width: 20,
                        height: 16,
                        radius: 2,
                        lineWidth: 1,
                        stroke: theme === 'dark' ? 'rgba(255, 255, 255, .2)' : 'rgba(0,0,0,.2)',
                        fill: theme === 'dark' ? '#182D45' : '#f4f4f4',
                    },
                    id: 'node-cluster-wrapper',
                    name: 'node-cluster-wrapper',
                });
                // 集群名字
                group.addShape('text', {
                    attrs: {
                        x: 0,
                        y: nodeH / 2 + 20,
                        fill: theme === 'dark' ? 'rgba(255, 255, 255, .65)' : 'rgba(0,0,0,.65)',
                        // text: `${nodeTextHandle(text, 8)}`,
                        text: `${fittingString(text, 50, 10)}`,
                        textBaseline: 'top',
                    },
                    id: 'node-cluster',
                    name: 'node-cluster',
                });
                const cluster = group.findById('node-cluster');
                const { x, y } = cluster.attr();
                // 集群图片
                group.addShape('image', {
                    attrs: {
                        x: x - 12,
                        y: y - 2,
                        img: Cluster,
                    },
                    id: 'node-cluster-pic',
                    name: 'node-cluster-pic',
                });
            }
            // 新建业务才显示
            if (node.supportRemove) {
                group.addShape('image', {
                    attrs: {
                        x: nodeW / 2 - 6,
                        y: -nodeH / 2,
                        width: 13,
                        height: 13,
                        cursor: 'pointer',
                        opacity: 0,
                        img: absUrl + closePng,
                    },
                    id: 'node-remove',
                    name: 'node-remove',
                });
            }
            return shape;
        },
        afterDraw(cfg, group) {
            const nameText = (group).findById('node-name');
            const editImage =  (group).findById('edit-image');
            const clusterWrapper =  (group).findById('node-cluster-wrapper');

            const textBBox = nameText.getBBox();
            if (editImage) {
                editImage.attr({
                    x: textBBox.maxX + 2,
                });
            }
            if (clusterWrapper) {
                const clusterText =  (group).findById('node-cluster');
                const clusterPic =  (group).findById('node-cluster-pic');
                const clusterTextBBox = clusterText.getBBox();
                clusterWrapper.attr({
                    x: -(clusterTextBBox.width + 24) / 2,
                    width: clusterTextBBox.width + 24,
                });
                clusterText.attr({
                    x: -(clusterTextBBox.width + 24) / 2 + 17,
                });
                clusterPic.attr({
                    x: -(clusterTextBBox.width + 24) / 2 + 2,
                });
            }
            (group).toFront();
        },
        update: (cfg, node) => {
            const group = node.getContainer();
            const textShape = group.findById('node-name');
            const nodeCircle = group.findById('node-circle');
            const nodeImage = group.findById('node-image');
            const entranceImage = group.findById('entrance-image');

            const nodeName = cfg.nameBak && cfg.nameBak !== cfg.name ? `${cfg.nameBak}(${cfg.name})` : cfg.name;
            textShape.attr('text', fittingString(nodeName || '', 60, 10));
            // 更新入口节点
            if (entranceImage && !cfg.isEntrance) {
                group.removeChild(entranceImage);
            }
            if (!entranceImage && cfg.isEntrance) {
                group.addShape('image', {
                    attrs: {
                        x: 0,
                        y: nodeH / 2 + 2,
                        width: 15,
                        height: 15,
                        cursor: 'pointer',
                        img: absUrl + enterPng,
                    },
                    id: 'entrance-image',
                    name: 'entrance-image',
                });
            }

            // 更新是否加入业务节点的样式
            if (cfg.isInBusiness === false) {
                nodeCircle.attr({
                    opacity: 0.4,
                    filter: 'grayscale(1)',
                });
                nodeImage.attr({
                    opacity: 0.4,
                    filter: 'grayscale(1)',
                });
            } else {
                nodeCircle.attr({
                    opacity: 1,
                    filter: 'grayscale(0)',
                });
                nodeImage.attr({
                    opacity: 1,
                    filter: 'grayscale(0)',
                });
            }
        },
        afterUpdate(cfg, item) {
            const group = (item).get('group');
            const nameText = group.findById('node-name');
            const editImage = group.findById('edit-image');
            const entranceImage = group.findById('entrance-image');
            const clusterWrapper = group.findById('node-cluster-wrapper');
            const textBBox = nameText.getBBox();
            if (editImage) {
                editImage.attr({
                    x: textBBox.maxX + 2,
                });
            }
            if (entranceImage) {
                entranceImage.attr({
                    x: textBBox.minX - 17,
                });
            }
            if (clusterWrapper) {
                const clusterText = group.findById('node-cluster');
                const clusterPic = group.findById('node-cluster-pic');
                const clusterTextBBox = clusterText.getBBox();
                clusterWrapper.attr({
                    x: -(clusterTextBBox.width + 24) / 2,
                    width: clusterTextBBox.width + 24,
                });
                clusterText.attr({
                    x: -(clusterTextBBox.width + 24) / 2 + 17,
                });
                clusterPic.attr({
                    x: -(clusterTextBBox.width + 24) / 2 + 2,
                });
            }
        },
        setState: (name, value, item) => {
            const group = (item).getContainer();
            const state = (item).getStates();
            const circleShape = group.findById('node-circle');
            const outCircleShape = group.findById('node-out-circle');
            const imgShape = group.findById('node-image');
            const removeShape = group.findById('node-remove');
            const model = (item).getModel();
            const nodeStatus = model.state && model.state.status ? model.state.status : 0;
            const theme = getStore('theme') || 'light';
            const stateHandlers = {
                // ? 新建业务使用
                hasSelected: function (value) {
                    if (value) {
                        circleShape.attr({
                            lineWidth: 3,
                            fill: nodeColors[nodeStatus],
                        });
                        imgShape.attr({
                            img: nodeActiveImgHandle(model.nodeType),
                        });
                    } else {
                        circleShape.attr({
                            lineWidth: 1,
                            fill: nodeFillColors[nodeStatus],
                            opacity: 1,
                        });
                        imgShape.attr({
                            img: getNodeImg(model.nodeType, nodeStatus),
                        });
                    }
                },
                hasFocus: function (value) {
                    if (value) {
                        outCircleShape.attr({
                            stroke:
                                theme === 'dark' ? 'rgba(255, 255, 255, 1)' : 'rgba(0, 0, 0, 1)',
                        });
                    } else {
                        outCircleShape.attr({
                            stroke:
                                theme === 'dark' ? 'rgba(255, 255, 255, 0)' : 'rgba(0, 0, 0, 0)',
                        });
                    }
                },
                active: function (value) {
                    if (model.isCenter && model.isSelected) {
                        return;
                    }
                    if (value) {
                        circleShape.attr({
                            lineWidth: 3,
                        });
                    } else {
                        if (state.length === 0) {
                            circleShape.attr({
                                lineWidth: 1,
                                opacity: 1,
                            });
                        }
                    }
                },
                hover: function (value) {
                    if (value) {
                        removeShape && removeShape.attr({
                            opacity: 1
                        });
                        // textShape.attr({ fill: '#40a9ff' });
                    } else {
                        removeShape && removeShape.attr({
                            opacity: 0
                        });
                    }
                },
            };
            stateHandlers[name](value);
            if (state.length === 0 && circleShape) {
                circleShape.attr({
                    lineWidth: 1,
                });
            }
        },
    },
    'single-node'
);

G6.registerNode(
    'custom-message-topo-node',
    {
        draw: (node, group) => {
            const theme = getStore('theme') || 'light';
            const shape = group.addShape('circle', {
                attrs: {
                    x: 0,
                    y: 0,
                    r: nodeW / 2,
                    height: nodeH,
                    lineWidth: 1,
                    fill: 'rgba(20, 134, 219, 0.12)',
                    stroke: '#1486DB',
                    opacity: 1,
                },
                id: 'node-circle',
                name: 'node-circle',
                draggable: true,
            });
            group.addShape('image', {
                attrs: {
                    x: -ImgW / 2,
                    y: -ImgW / 2,
                    width: ImgW,
                    height: ImgH,
                    cursor: 'pointer',
                    opacity: 1,
                    img: getNodeImg(node.workloadKind, 0),
                },
                name: 'node-image',
                id: 'node-image',
                draggable: true,
            });

            group.addShape('text', {
                attrs: {
                    x: 0,
                    y: nodeH / 2 + 6,
                    textAlign: 'center',
                    textBaseline: 'top',
                    fontSize: 12,
                    text: fittingString(node.workloadName || `${node.ip}${node.port ? `:${node.port}` : ''}`, 60, 12),
                    fill: theme === 'dark' ? 'rgba(255, 255, 255, 0.85)' : 'rgba(0, 0, 0, 0.85)',
                },
                id: 'node-name',
                name: 'node-name',
            });
            const namespaceClusterName = `${node.clusterName}(${node.namespace})`;
            // 集群命名空间名字
            group.addShape('text', {
                attrs: {
                    x: 0,
                    y: nodeH / 2 + 22,
                    textAlign: 'center',
                    textBaseline: 'top',
                    fill: theme === 'dark' ? 'rgba(255, 255, 255, .45)' : 'rgba(0,0,0,.45)',
                    text: `${fittingString(namespaceClusterName, 70, 10)}`,
                },
                id: 'node-cluster-namespace',
                name: 'node-cluster-namespace',
            });
            return shape;
        },
        afterDraw(cfg, group) {
        },
        update: (cfg, node) => {
        },
        afterUpdate(cfg, item) {
        },
        setState: (name, value, item) => {
            const group = (item ).getContainer();
            const state = (item).getStates();
            const circleShape = group.findById('node-circle');
            const stateHandlers = {
                active: function (value) {
                    if (value) {
                        circleShape.attr({
                            lineWidth: 3,
                        });
                    } else {
                        if (state.length === 0) {
                            circleShape.attr({
                                lineWidth: 1,
                                opacity: 1,
                            });
                        }
                    }
                },

            };
            stateHandlers[name](value);
            if (state.length === 0 && circleShape) {
                circleShape.attr({
                    lineWidth: 1,
                });
            }
        },
    },
    'single-node'
);
